(use ./common)

(defn fade (t)
  (* t t t (+ (* t (- (* t 6) 15)) 10)))

(defn lerp (t a b)
  (+ a (* t (- b a))))

(defn grad (hash x y z)
  (def h (band hash 15))   #CONVERT LO 4 BITS OF HASH CODE
  (def u (if (< h 8) x y)) #INTO 12
  (def v (cond (< h 4) y   #GRADIENT DIRECTIONS.
               (or (= h 12) (= h 14)) x
               z))
  (+
     (if (= 0 (band h 1)) u (- u))
     (if (= 0 (band h 2)) v (- v))))

(defn new-noise (seed)
 (var q (shuffle (range 0 256) seed)) #Gen new.
 (defn p (n)
  (q (% n (length q))))
#Can't overflow because of p.

  (defn improved-noise (&opt x y z)
    (default x 0) (default y 0) (default z 0)
    (def [X Y Z] (map band (map math/floor [x y z]) [255 255 255]))
    (var [x y z] (map |(- $ (math/floor $)) [x y z]))
    (def [u v w] (map fade [x y z]))
    (let (
          A  (+ (p X) Y)
          AA (+ (p A) Z)
          AB (+ (p (inc A)) Z)
          B  (+ (p (inc X)) Y)
          BA (+ (p B) Z)
          BB (+ (p (inc B)) Z)
          )
      ##(pp [A AA AB : B BA BB])
      (lerp w (lerp v
                    (lerp u
                          (grad (p AA)      x       y     z)
                          (grad (p BA) (dec x)      y     z))
                    (lerp u
                          (grad (p AB)      x  (dec y)    z)
                          (grad (p BB) (dec x) (dec y)    z)))
            (lerp v
                  (lerp u
                        (grad (p (inc AA))      x  y (dec z))
                        (grad (p (inc BA)) (dec x) y (dec z)))
                  (lerp u
                        (grad (p (inc AB)) x (dec y) (dec z))
                        (grad (p (inc BB)) (dec x) (dec y) (dec z))))))))
